package xyz.hzxiao.handler.init;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.codec.http.cors.CorsConfigBuilder;
import io.netty.handler.codec.http.cors.CorsHandler;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import xyz.hzxiao.handler.transmit.WebSocketBinaryMessageHandler;
import xyz.hzxiao.handler.transmit.WebSocketTextMessageHandler;

/**
 * 初始化WebSocket连接通道处理器
 *
 * @author ：FuXx
 * @className : xyz.hzxiao.handler.init.WebSocketInitChannelHandler
 * @since ：2025/1/10
 */
public class WebSocketInitChannelHandler extends ChannelInitializer<SocketChannel> {

    private static final int MAX_AGGREGATE_SIZE = 1024 * 1024 * 1024;

    private static final String WEBSOCKET_ENDPOINT = "/ws";

    private static final int MAX_FRAME_SIZE = 65535;

    /**
     * This method will be called once the {@code Channel} was registered. After the method returns this instance
     * will be removed from the {@code ChannelPipeline} of the {@code Channel}.
     *
     * @param ch the {@code Channel} which was registered.
     */
    @Override
    protected void initChannel(SocketChannel ch) {
        ch.pipeline()
                .addLast(new HttpRequestDecoder())
                .addLast(new HttpResponseEncoder())
                .addLast(new ChunkedWriteHandler())
                .addLast(new HttpObjectAggregator(MAX_AGGREGATE_SIZE))
                .addLast(new CorsHandler(CorsConfigBuilder.forAnyOrigin()
                        .allowNullOrigin()
                        .allowCredentials()
                        .build()))
                .addLast(new WebSocketServerChannelHandler())
                .addLast(new WebSocketServerProtocolHandler(
                        WEBSOCKET_ENDPOINT, null, true, MAX_FRAME_SIZE, true))
                .addLast(new WebSocketTextMessageHandler())
                .addLast(new WebSocketBinaryMessageHandler());
    }
}
